Skip to content

feat: SSR compatibility PoC for journey-client and oidc-client#566

Draft
ryanbas21 wants to merge 1 commit into
mainfrom
ssr-jc
Draft

feat: SSR compatibility PoC for journey-client and oidc-client#566
ryanbas21 wants to merge 1 commit into
mainfrom
ssr-jc

Conversation

@ryanbas21

Copy link
Copy Markdown
Collaborator

Summary

This is a complete proof of concept — not finished work. It demonstrates the changes needed to make journey-client and oidc-client work in server-side rendering environments (SvelteKit, Next.js, etc.).

Problem

  • @forgerock/storage eagerly references sessionStorage/localStorage globals, crashing on import in Node.js
  • createAuthorizeUrl couples PKCE generation with sessionStorage, preventing server-side authorize URL creation
  • window.location.assign() in redirect() has no server guard

Changes

Storage (@forgerock/storage)

  • Replace eager browser global references with lazy globalThis access via getBrowserStorage()
  • SSR callers use existing type: 'custom' with a no-op adapter — no new types needed

Journey Client (@forgerock/journey-client)

  • Add optional storage config to JourneyClientConfig (defaults to sessionStorage)
  • Guard redirect() with typeof window check
  • Export createJourneyObject for client-side step reconstitution after SSR

OIDC / PKCE (@forgerock/sdk-oidc, @forgerock/oidc-client)

  • Decouple PKCE generation from storage — createAuthorizeUrl now returns { url, verifier, state } instead of writing to sessionStorage
  • Callers persist PKCE values however they choose (cookies, server session, etc.)
  • token.exchange() accepts optional pkceValues parameter to skip sessionStorage lookup
  • Browser background flow still uses sessionStorage internally (unchanged behavior)

SvelteKit PoC (e2e/svelte-app)

  • Demonstrates full end-to-end flow against the AM mock API:
    1. Server-side journey start() → SSR-rendered login form
    2. Client-side credential submission via next()
    3. Server-side PKCE authorize URL generation with cookie-based verifier persistence
    4. Server-side token exchange → tokens received

Test plan

  • nx run storage:test — 21 tests pass
  • nx run journey-client:test — 193 tests pass
  • nx run sdk-oidc:test — 26 tests pass
  • nx run oidc-client:test — 21 tests pass
  • nx run davinci-client:test — 226 tests pass
  • SvelteKit PoC: start am-mock-api:serve + vite dev in e2e/svelte-app, verify SSR rendering and token exchange

@changeset-bot

changeset-bot Bot commented Apr 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 641ee76

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fcf0deaf-1b19-48b7-90a0-e691df5a1f8c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ssr-jc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ryanbas21 ryanbas21 force-pushed the ssr-jc branch 3 times, most recently from 3088dc6 to 1e39459 Compare April 9, 2026 16:53
@nx-cloud

nx-cloud Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit c01705c

Command Status Duration Result
nx affected -t build lint test typecheck e2e-ci ❌ Failed 1m 35s View ↗

💡 Dealing with memory or CPU issues? See memory and CPU details with the resource usage add-on ↗.


☁️ Nx Cloud last updated this comment at 2026-06-26 19:07:44 UTC

@ryanbas21 ryanbas21 force-pushed the ssr-jc branch 2 times, most recently from 754ed3c to 32a9242 Compare June 17, 2026 16:04
@ryanbas21 ryanbas21 force-pushed the ssr-jc branch 4 times, most recently from 2398cad to c01705c Compare June 26, 2026 19:04

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud is proposing a fix for your failed CI:

These changes fix the build and typecheck failures introduced by the incomplete migration of createAuthorizeUrl to return AuthorizeUrlResult instead of string. We restored the RTK error-handling helpers (isFetchBaseQueryError, toDispatchError, toAuthorizationError) that were removed from authorize.request.utils.ts but were still imported by authorize.request.micros.ts, and updated all callsites and tests to extract .url from the new return shape.

Warning

  • We could not verify this fix.
  • The suggested diff is too large to display here, but you can view it on Nx Cloud ↗

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally vpxo-fbnU

Apply fix locally with your editor ↗   View interactive diff ↗



🎓 Learn more about Self-Healing CI on nx.dev

Make journey-client and oidc-client importable and usable in Node.js/SSR
environments by eliminating eager browser global references and decoupling
PKCE generation from sessionStorage.

Storage: Replace eager sessionStorage/localStorage references with lazy
globalThis access via getBrowserStorage(). Add configurable storage option
to JourneyClientConfig so SSR callers can provide a custom noop adapter.

PKCE: Decouple generation from storage — createAuthorizeUrl now returns
{ url, verifier, state } instead of writing to sessionStorage. Callers
persist PKCE values however they choose (cookies, server session, etc.).
Token exchange accepts optional pkceValues parameter to skip sessionStorage.

Guard redirect() with typeof window check for server environments.
Export createJourneyObject for client-side step reconstitution.

SvelteKit PoC in e2e/svelte-app demonstrates the full flow:
server-side journey start, client-side credential submission,
server-side PKCE authorize URL generation with cookie-based verifier
persistence, and server-side token exchange against the AM mock API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant